/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { Decorator } from 'ts-morph';
import { ClassAnalysis, PropertyKind, TypeStructure } from '../Types';
import { DecoratorConstants } from '../constants';
import { Logger } from '../logger/Logger';
import { SendableMergeabilityRegistry } from './SendableMergeabilityRegistry';

/**
 * Sendable类合并性检查器
 *
 * 检查是否可以将原始类和Sendable类合并为单一Sendable类。
 *
 * 合并条件：
 * 1. 类层级无非TurboTrans装饰器
 * 2. 类无泛型参数
 * 3. 每个属性无非TurboTrans装饰器
 * 4. 每个属性是Sendable允许类型或可合并的@Serializable类
 * 5. 父类也必须可合并
 *
 * 合并后的类：
 * - 移除所有TurboTrans装饰器
 * - 添加 @Sendable 装饰器
 * - 类名保持不变
 */
export class SendableMergeChecker {
  // TurboTrans装饰器集合（用于快速查找）
  private static readonly TURBO_TRANS_DECORATORS = new Set(DecoratorConstants.SERIAL_DECORATORS);

  // Sendable允许的基础类型（根据官方文档）
  private static readonly SENDABLE_PRIMITIVE_KINDS = new Set<PropertyKind>([
    PropertyKind.STRING,
    PropertyKind.NUMBER,
    PropertyKind.BOOLEAN,
    PropertyKind.BIGINT,
    PropertyKind.NULL,
    PropertyKind.UNDEFINED,
  ]);

  // TODO: 这里的白名单暂时还没写全
  // Sendable允许的Collections容器类型
  private static readonly SENDABLE_COLLECTION_KINDS = new Set<PropertyKind>([
    PropertyKind.COLLECTIONS_ARRAY,
    PropertyKind.COLLECTIONS_SET,
    PropertyKind.COLLECTIONS_MAP,
  ]);

  /**
   * 检查类的Sendable合并性
   * @param classAnalysis 类分析结果
   * @returns 合并性分析结果
   */
  public static check(classAnalysis: ClassAnalysis): boolean {
    // 条件1: 检查类级别装饰器
    const classDecorators = classAnalysis.originalClass?.getDecorators() || [];
    const nonTurboTransDecorators = this.getNonTurboTransDecorators(classDecorators);
    if (nonTurboTransDecorators.length > 0) {
      // TODO: 完善debug日志
      Logger.debug(`${classAnalysis.className}类有其他装饰器`);
      return false;
    }

    // 条件2: 检查泛型参数
    if (classAnalysis.generics.isGeneric) {
      // TODO: 完善debug日志
      Logger.debug(`${classAnalysis.className}类有泛型参数`);
      return false;
    }

    // 条件3 & 4: 检查属性装饰器和类型
    const invalidProperties: string[] = [];
    for (const property of classAnalysis.properties) {
      // 条件3: 检查属性装饰器
      const propertyNode = classAnalysis.originalClass?.getProperty(property.name);
      if (propertyNode) {
        const propDecorators = propertyNode.getDecorators();
        const nonTurboPropDecorators = this.getNonTurboTransDecorators(propDecorators);
        if (nonTurboPropDecorators.length > 0) {
          // TODO: 完善debug日志
          invalidProperties.push(`${property.name} (装饰器: ${nonTurboPropDecorators.join(', ')})`);
          continue;
        }
      }

      // 条件4: 检查属性类型是否为Sendable允许类型
      if (!this.isSendableType(property.type, classAnalysis)) {
        // TODO: 完善debug日志
        invalidProperties.push(`${property.name} (类型: ${property.type.sourceText})`);
      }
    }

    if (classAnalysis.originalClass) {
      for (const method of classAnalysis.originalClass.getMethods()) {
        // 条件3: 检查方法装饰器
        const methodDecorators = method.getDecorators();
        const nonTurboPropDecorators = this.getNonTurboTransDecorators(methodDecorators);
        if (nonTurboPropDecorators.length > 0) {
          invalidProperties.push(`${method.getName()} (装饰器: ${nonTurboPropDecorators.join(', ')})`);
        }
      }
    }

    if (invalidProperties.length > 0) {
      // TODO: 完善debug日志
      Logger.debug(invalidProperties.join('\n'));
      return false;
    }

    // 条件5: 递归检查父类
    if (classAnalysis.inheritance.isInherited && classAnalysis.inheritance.baseClassAnalysis) {
      // TODO: 完善debug日志
      Logger.debug(`${classAnalysis.className}的父类不可合并`);
      return this.check(classAnalysis.inheritance.baseClassAnalysis as ClassAnalysis);
    }

    // 所有条件满足，可以合并
    return true;
  }

  /**
   * 获取非TurboTrans装饰器列表
   * @param decorators 装饰器数组
   * @returns 非TurboTrans装饰器名称列表
   */
  private static getNonTurboTransDecorators(decorators: Decorator[]): string[] {
    return decorators
      .map(d => d.getName())
      .filter(name => !this.TURBO_TRANS_DECORATORS.has(name));
  }

  /**
   * 检查类型是否为Sendable允许类型
   * @param typeStructure 类型结构
   * @param contextClass 当前类分析上下文（用于查找自定义类型）
   * @returns 是否为Sendable允许类型
   */
  private static isSendableType(typeStructure: TypeStructure, contextClass: ClassAnalysis): boolean {
    const { kind } = typeStructure;

    // 基础类型
    if (this.SENDABLE_PRIMITIVE_KINDS.has(kind)) {
      return true;
    }

    // Collections容器类型
    if (this.SENDABLE_COLLECTION_KINDS.has(kind)) {
      // 递归检查泛型参数类型
      return typeStructure.args.every(arg => this.isSendableType(arg, contextClass));
    }

    // 自定义类类型（OBJECT类型）
    if (kind === PropertyKind.OBJECT && typeStructure.classDetails) {
      // 检查是否为可合并的@Serializable类
      const classDetails = typeStructure.classDetails;
      if (classDetails.classDecl.getDecorator('Sendable')) {
        return true;
      }

      const className = classDetails.classDecl.getNameOrThrow();
      // 从全局注册表查询合并性
      const canMerge = SendableMergeabilityRegistry.canMerge(className);

      if (canMerge === undefined) {
        // 类还未分析（可能在其他文件中，或循环引用）
        // 保守处理：假设不可合并
        // 注意：在双阶段分析架构下，这种情况应该很少发生
        return false;
      }

      return canMerge;
    }

    // Optional/Nullable/Union类型：所有成员都必须是Sendable类型
    if ((kind === PropertyKind.UNION || kind === PropertyKind.OPTIONAL || kind === PropertyKind.NULLABLE) &&
      typeStructure.unionDetails) {
      return typeStructure.unionDetails.every(member => this.isSendableType(member, contextClass));
    }

    // 其他类型（Array, Set, Map, Record等）不是Sendable类型
    return false;
  }
}
